#pragma once
#include "Globals.h"

class Input
{
private:

	IDirectInput8*			DIObject;			//Input Device: Instantiated Object
	LPDIRECTINPUTDEVICE8	DIKeyboard;			//Input Device: Keyboard
	LPDIRECTINPUTDEVICE8	DIMouse;			//Input Device: Mouse
	char					buffer[256];		//Condition: Keyboard
	POINT					CursorPosition;		//Condition: Cursor Postion
	DIMOUSESTATE			mouseState;			//Condition: Mouse State

	HRESULT hr;

public:

	inline static Input* Into()      
	{static Input engine;return &engine;}

	void Initialize(HWND hWnd,HINSTANCE hInst)
	{
		DirectInput8Create												//Create DIObject 
			(hInst, DIRECTINPUT_VERSION,
			IID_IDirectInput8, (void**)&DIObject, NULL); 

		DIObject->CreateDevice(GUID_SysKeyboard, &DIKeyboard, NULL);	//Create DIKeyboard Device
		DIObject->CreateDevice(GUID_SysMouse, &DIMouse, NULL);			//Create DIMouse Device

		DIKeyboard->SetDataFormat(&c_dfDIKeyboard);		//Set DIKeyboard format
		DIMouse->SetDataFormat(&c_dfDIMouse);			//Set DIMouse format

		DIKeyboard->SetCooperativeLevel(hWnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);
		DIMouse->SetCooperativeLevel(hWnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);

		hr = DIKeyboard->Acquire();		//Aquire the keyboard
		hr = DIMouse->Acquire();		//Aquire the mouse
		::ZeroMemory(buffer,sizeof(buffer));
	}
	void UpdateInput(HWND hWnd)
	{
		GetCursorPos(&CursorPosition);
		ScreenToClient(hWnd,&CursorPosition);

		DIKeyboard->GetDeviceState	(sizeof(buffer),(LPVOID)&buffer);
		DIMouse->GetDeviceState		(sizeof(mouseState), (void*)&mouseState); 

		HRESULT hr = DIKeyboard->GetDeviceState(sizeof(buffer), (void*)&buffer);
		if(FAILED(hr))
		{	
			ZeroMemory(buffer, sizeof(buffer));

			hr = DIKeyboard->Acquire();		// attempt to re-acquire the device if unable to GetDeviceState
			hr = DIMouse->Acquire();		//Aquire the mouse
		}
	}
	bool isClicked(int Specification)
	{
		switch(Specification)
		{
		case LEFT:	if(mouseState.rgbButtons[0])	return true;
		case RIGHT:	if(mouseState.rgbButtons[1])	return true;
		case MIDDLE:if(mouseState.rgbButtons[2])	return true;
		}
		return false;
	}

	bool isWithin(RECT Compare)
	{
		if(CursorPosition.x < Compare.right
			&& CursorPosition.x > Compare.left
			&& CursorPosition.y > Compare.top
			&& CursorPosition.y < Compare.bottom
			)
			return true;
		return false;
	}

	int  AquireInput()	//Returns and enumerated direction value, debug purposes only
	{

		hr = DIKeyboard->GetDeviceState(sizeof(buffer),(LPVOID)&buffer );		//Check the keyboard


		if(buffer[DIK_UP] & 0x80)		{return DIR_SHEIGHTU;}
		if(buffer[DIK_DOWN] & 0x80)		{return DIR_SHEIGHTD;}
		if(buffer[DIK_LEFT] & 0x80)		{return DIR_SWIDTHD;}
		if(buffer[DIK_RIGHT] & 0x80)	{return DIR_SWIDTHU;}

		if(buffer[DIK_W] & 0x80)		{return DIR_UP;}
		if(buffer[DIK_S] & 0x80)		{return DIR_DOWN;}
		if(buffer[DIK_A] & 0x80)		{return DIR_LEFT;}
		if(buffer[DIK_D] & 0x80)		{return DIR_RIGHT;}	
		if(buffer[DIK_Q] & 0x80)		{return DIR_SALLU;}
		if(buffer[DIK_E] & 0x80)		{return DIR_AALLD;}	

		return 0;
	}

	~Input()
	{
		DIKeyboard->Unacquire();	//Let the Keyboard go
		DIMouse->Unacquire();		//Let the mouse go
	}

};